/**
 * @file mem.c
 * Memory source for TrayInfo.
 */

/* Memory support added by Laszlo Ashin <kodest@gmail.com> */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "trayinfo.h"
#include "utils.h"

/** Source handle. */
static source_handle_t *mem_sh;

static int
mem_write(/*@unused@*/ double now, /*@unused@*/ int fd)
{
	const char *idlist[] = {
		"MemTotal",
		"MemFree",
		"Buffers",
		"Cached",
		"SwapTotal",
		"SwapFree"
	};
	typedef /*@null@*/ char * nullstr_t;
	nullstr_t vallist[] = { NULL, NULL, NULL, NULL, NULL, NULL };
	double flist[6];
	int i, bo = 1;

	(void)collect_data_from_file(
		"/proc/meminfo",
		":", 6, idlist, vallist
	);
	for (i = 0; i < 6; ++i) {
		char *ep;
		if (vallist[i]) {
			int r = parse_prefixed_string(vallist[i], flist + i, &ep);
			if (r != 0 || *ep != 'B') {
				bo = 0;
			}
			free(vallist[i]);
		} else {
			bo = 0;
		}
	}
	if (bo == 0) {
		return 0;
	} else {
		double ram, swap;
		ram = flist[0] - flist[1] - flist[2] - flist[3];
		ram = ram * 99.0f / flist[0];
		swap = flist[4] - flist[5];
		swap = swap * 99.0f / flist[4];
		return show("%02.0f%%%02.0f", ram, swap);
	}
}

int
init_module(module_phase_t phase)
{
	switch (phase) {
	case MODULE_PHASE_INIT: {
		source_t source = {
			.name = "mem",
			.write = mem_write,
		};
		mem_sh = register_source(&source);
		return (mem_sh == NULL);
	}
	case MODULE_PHASE_EXIT:
		return forget_source(mem_sh);
	}
}
